import Taro from "@tarojs/taro";
import qs from "qs";
import { serverMap, IServer } from "@/common/config";
import { hex_sha1 } from "./security/sha1";

interface Iparams {
  data: any;
  flag: keyof IServer;
  api: string;
}

type Istatus = "ok" | "buseness";

export interface TokenData {
  access_token: string;
  expire_time: string;
  renew_flag: string;
}

let token: TokenData = {
  access_token: "",
  expire_time: "",
  renew_flag: "",
};

function get_params(api, params, flag) {
  let data = {
    api,
    ...params,
  };
  const access_token = getToken().access_token;
  if (access_token) {
    data.auth = access_token;
  }
  data = get_signature(data, flag);
  return data;
}

function get_signature(params, flag) {
  let data = {
    flag,
    timestamp: new Date().getTime(),
    ...params,
  };
  data["sign"] = calc_signature(data);
  return data;
}

function calc_signature(parms) {
  let sign = "";
  let tmpArr: string[] = [];
  let tmpStr = "";
  let result = "";
  for (let key in parms) {
    tmpArr.push(key);
  }
  tmpArr = tmpArr.sort().reverse();

  for (let i = 0; i < tmpArr.length; i++) {
    if (typeof parms[tmpArr[i]] === "object") {
      tmpStr =
        tmpStr + tmpArr[i].toLowerCase() + JSON.stringify(parms[tmpArr[i]]);
    } else {
      tmpStr = tmpStr + tmpArr[i].toLowerCase() + parms[tmpArr[i]];
    }
  }
  console.log("签名字符串------->>>", tmpStr);

  let sha = hex_sha1(utf16to8(tmpStr));
  let shaLength = sha.length;
  let count = parseInt(String(tmpArr.length * 1.4));

  if (count >= shaLength) {
    count = shaLength;
  }

  let step = parseInt(String(shaLength / count));

  for (let i = 0; i < count; i++) {
    let num = Math.floor(i * step);
    sign = sign + sha.charAt(num);
  }
  result = sign;

  return result;
}

function utf16to8(str) {
  let out, i, len, c;
  out = "";
  len = str.length;
  for (i = 0; i < len; i++) {
    c = str.charCodeAt(i);
    if (c >= 0x0001 && c <= 0x007f) {
      out += str.charAt(i);
    } else if (c > 0x07ff) {
      out += String.fromCharCode(0xe0 | ((c >> 12) & 0x0f));
      out += String.fromCharCode(0x80 | ((c >> 6) & 0x3f));
      out += String.fromCharCode(0x80 | ((c >> 0) & 0x3f));
    } else {
      out += String.fromCharCode(0xc0 | ((c >> 6) & 0x1f));
      out += String.fromCharCode(0x80 | ((c >> 0) & 0x3f));
    }
  }
  return out;
}

export function getToken() {
  if (token.access_token) {
    return token;
  }
  if (Taro.getStorageSync("token")) {
    token = Taro.getStorageSync("token");
  }
  return token;
}

export function setToken(value: TokenData) {
  token = value;
  Taro.setStorageSync("token", token);
}

export function removeToken() {
  token = { access_token: "", expire_time: "", renew_flag: "" };
  Taro.removeStorageSync("token");
}

export function request(
  params: Iparams
): Promise<{ status: Istatus; [key: string]: any }> {
  const baseUrl = serverMap[params.flag].url;
  return Taro.request({
    url: baseUrl,
    data: qs.stringify(get_params(params.api, params.data, params.flag)),
    method: "POST",
    header: {
      "Content-Type": "application/x-www-form-urlencoded",
    },
  })
    .then((res) => {
      const { statusCode, data } = res;
      if (statusCode >= 200 && statusCode < 300) {
        if (data.status !== "ok") {
          console.log("data.code------->>>", data.code);
          switch (data.code) {
            case "30007":
            case "30008":
            case "30009":
              Taro.navigateTo({
                url: "/pages/loginGuide/index",
              });
              break;

            default:
              Taro.showModal({
                title: "提示",
                content: data.msg,
                showCancel: false,
              });
          }
        }
        return data;
      } else {
        throw new Error(`网络请求错误，状态码${statusCode}`);
      }
    })
    .catch((err) => {
      console.log("请求失败", err);
    });
}
